﻿using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Zhao.Common.Helper;

namespace Zhao.Repository.Base
{
    public interface IBaseRepository<TEntity> where TEntity : class
    {
        #region 同步

        #region 查询
        /// <summary>
        /// 根据主键获取一条数据，primaryKey必须为主键
        /// </summary>
        /// <param name="primaryKey">主键</param>
        /// <param name="blnUseCache">是否缓存</param>
        /// <returns>TEntity</returns>
        TEntity Query<T>(T primaryKey, bool blnUseCache = false);

        /// <summary>
        /// 根据条件表达式获取一条数据
        /// </summary>
        /// <param name="expression">条件表达式</param>
        /// <param name="blnUseCache">是否缓存</param>
        /// <returns>TEntity</returns>
        TEntity Query(Expression<Func<TEntity, bool>> expression, bool blnUseCache = false);

        TEntity QueryOrder(Expression<Func<TEntity, bool>> expression, string strOrderByFileds = null, bool blnUseCache = false);

        TEntity QueryParameterOrder(string strWhere, SugarParameter[] parameters, string strOrderByFileds = null, bool blnUseCache = false);

        /// <summary>
        /// 根据条件表达式取数据
        /// </summary>
        /// <param name="expression">条件表达式</param>
        /// <param name="strOrderByFileds">排序</param>
        /// <param name="blnUseCache">是否缓存</param>
        /// <returns></returns>
        List<TEntity> QueryList(Expression<Func<TEntity, bool>> expression, string strOrderByFileds = null, bool blnUseCache = false);

        /// <summary>
        /// 根据条件表达式取数据
        /// </summary>
        /// <param name="expression">条件表达式</param>
        /// <param name="strOrderByFileds">排序</param>
        /// <param name="top">前几条</param>
        /// <param name="blnUseCache">是否缓存</param>
        /// <returns></returns>
        List<TEntity> QueryList(Expression<Func<TEntity, bool>> expression, int top, string strOrderByFileds = null, bool blnUseCache = false);

        /// <summary>
        /// 单表通用分页查询
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="strOrderByFileds"></param>
        /// <param name="intPageIndex"></param>
        /// <param name="intPageSize"></param>
        /// <returns></returns>
        PageModel<TEntity> QueryPage(Expression<Func<TEntity, bool>> whereExpression, string strOrderByFileds = null, int intPageIndex = 1, int intPageSize = 20);

        int QueryCount(Expression<Func<TEntity, bool>> whereExpression);
        #endregion

        #region 添加

        /// <summary>
        /// 添加一条数据
        /// </summary>
        /// <param name="entity">entity</param>
        /// <returns>int</returns>
        int Add(TEntity entity);

        /// <summary>
        /// 批量添加数据
        /// </summary>
        /// <param name="entities">List<T></param>
        /// <returns>int</returns>
        int Add(List<TEntity> entities);

        #endregion

        #region 修改

        /// <summary>
        /// 修改一条数据
        /// </summary>
        /// <param name="entity">entity</param>
        /// <returns>bool</returns>
        bool Update(TEntity entity);

        /// <summary>
        /// 修改一条数据
        /// </summary>
        /// <param name="columns">指定列表达式</param>
        /// <param name="where">条件表达式</param>
        /// <returns>bool</returns>
        bool Update(Expression<Func<TEntity, TEntity>> columns, Expression<Func<TEntity, bool>> where);

        /// <summary>
        /// 批量修改数据
        /// </summary>
        /// <param name="entities">entities</param>
        /// <returns>int</returns>
        int Update(List<TEntity> entities);
        #endregion

        #region 删除

        /// <summary>
        /// 删除一条数据
        /// </summary>
        /// <param name="primaryKey">主键</param>
        /// <returns>bool</returns>
        bool Delete<T>(T primaryKey);

        /// <summary>
        /// 删除一条数据
        /// </summary>
        /// <param name="entity">entity</param>
        /// <returns>bool</returns>
        bool Delete(TEntity entity);

        /// <summary>
        /// 批量删除数据
        /// </summary>
        /// <param name="ids">主键集合</param>
        /// <returns>int</returns>
        int Delete(object[] ids);

        /// <summary>
        /// 批量删除数据
        /// </summary>
        /// <param name="where">条件表达式</param>
        /// <returns>int</returns>
        int Delete(Expression<Func<TEntity, bool>> where);

        #endregion

        #endregion

        #region 异步

        #region 查询
        /// <summary>
        /// 根据主键获取一条数据，primaryKey必须为主键
        /// </summary>
        /// <param name="primaryKey">主键</param>
        /// <param name="blnUseCache">是否缓存</param>
        /// <returns>TEntity</returns>
        Task<TEntity> QueryAsync<T>(T primaryKey, bool blnUseCache = false);

        /// <summary>
        /// 根据条件表达式获取一条数据
        /// </summary>
        /// <param name="expression">条件表达式</param>
        /// <param name="blnUseCache">是否缓存</param>
        /// <returns>TEntity</returns>
        Task<TEntity> QueryAsync(Expression<Func<TEntity, bool>> expression, bool blnUseCache = false);


        Task<TEntity> QueryOrderAsync(Expression<Func<TEntity, bool>> expression, string strOrderByFileds = null, bool blnUseCache = false);

        /// <summary>
        /// 根据条件表达式取数据
        /// </summary>
        /// <param name="expression">条件表达式</param>
        /// <param name="strOrderByFileds">排序</param>
        /// <param name="blnUseCache">是否缓存</param>
        /// <returns></returns>
        Task<List<TEntity>> QueryListAsync(Expression<Func<TEntity, bool>> expression, string strOrderByFileds = null, bool blnUseCache = false);

        /// <summary>
        /// 根据条件表达式取数据
        /// </summary>
        /// <param name="expression">条件表达式</param>
        /// <param name="strOrderByFileds">排序</param>
        /// <param name="top">前几条</param>
        /// <param name="blnUseCache">是否缓存</param>
        /// <returns></returns>
        Task<List<TEntity>> QueryListAsync(Expression<Func<TEntity, bool>> expression, int top, string strOrderByFileds = null, bool blnUseCache = false);

        /// <summary>
        /// 单表通用分页查询
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="strOrderByFileds"></param>
        /// <param name="intPageIndex"></param>
        /// <param name="intPageSize"></param>
        /// <returns></returns>
        Task<PageModel<TEntity>> QueryPageAsync(Expression<Func<TEntity, bool>> whereExpression, string strOrderByFileds = null, int intPageIndex = 1, int intPageSize = 20);
        Task<int> QueryCountAsync(Expression<Func<TEntity, bool>> whereExpression);
        /// <summary> 
        ///分页查询-多表查询
        /// </summary> 
        /// <typeparam name="T">实体1</typeparam> 
        /// <typeparam name="T2">实体2</typeparam> 
        /// <typeparam name="T3">实体3</typeparam>
        /// <typeparam name="TResult">返回对象</typeparam>
        /// <param name="joinExpression">关联表达式 (join1,join2) => new object[] {JoinType.Left,join1.UserNo==join2.UserNo}</param> 
        /// <param name="selectExpression">返回表达式 (s1, s2) => new { Id =s1.UserNo, Id1 = s2.UserNo}</param>
        /// <param name="whereLambda">查询表达式 (w1, w2) =>w1.UserNo == "")</param> 
        /// <param name="strOrderByFileds"></param> 
        /// <param name="intPageIndex"></param> 
        /// <param name="intPageSize"></param> 
        /// <returns>值</returns>
        //Task<PageModel<TResult>> QueryMuchAsync<T, T2, T3, TResult>(
        //     Expression<Func<T, T2, T3, object[]>> joinExpression,
        //     Expression<Func<T, T2, T3, TResult>> selectExpression,
        //     Expression<Func<T, T2, T3, bool>> where = null,
        //     string strOrderByFileds = null,
        //     int intPageIndex = 1,
        //     int intPageSize = 20);

        #endregion

        #region 添加

        /// <summary>
        /// 添加一条数据
        /// </summary>
        /// <param name="entity">entity</param>
        /// <returns>int</returns>
        Task<int> AddAsync(TEntity entity);

        /// <summary>
        /// 批量添加数据
        /// </summary>
        /// <param name="entities">List<T></param>
        /// <returns>int</returns>
        Task<int> AddAsync(List<TEntity> entities);

        #endregion

        #region 修改

        /// <summary>
        /// 修改一条数据
        /// </summary>
        /// <param name="entity">entity</param>
        /// <returns>bool</returns>
        Task<bool> UpdateAsync(TEntity entity);

        /// <summary>
        /// 修改一条数据
        /// </summary>
        /// <param name="columns">指定列表达式</param>
        /// <param name="where">条件表达式</param>
        /// <returns>bool</returns>
        Task<bool> UpdateAsync(Expression<Func<TEntity, TEntity>> columns, Expression<Func<TEntity, bool>> where);

        /// <summary>
        /// 批量修改数据
        /// </summary>
        /// <param name="entities">entities</param>
        /// <returns>int</returns>
        Task<int> UpdateAsync(List<TEntity> entities);
        #endregion

        #region 删除

        /// <summary>
        /// 删除一条数据
        /// </summary>
        /// <param name="primaryKey">主键</param>
        /// <returns>bool</returns>
        Task<bool> DeleteAsync<T>(T primaryKey);

        /// <summary>
        /// 删除一条数据
        /// </summary>
        /// <param name="entity">entity</param>
        /// <returns>bool</returns>
        Task<bool> DeleteAsync(TEntity entity);

        /// <summary>
        /// 批量删除数据
        /// </summary>
        /// <param name="ids">主键集合</param>
        /// <returns>int</returns>
        Task<int> DeleteAsync(object[] ids);

        /// <summary>
        /// 批量删除数据
        /// </summary>
        /// <param name="where">条件表达式</param>
        /// <returns>int</returns>
        Task<int> DeleteAsync(Expression<Func<TEntity, bool>> where);

        #endregion

        #endregion

    }
}
